#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <shmem.h>
#include <msg_queue.h>

static struct msg_param msg_para;

#define MODULE "msgc_control_gather"

#define N 64

//全局变量

//发送命令缓冲区
unsigned char send_buf[128] = {0x02,0xb7,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x00,0x00,0x02};

typedef int BOOL;

union val
{
    int val_i;
    float val_f;
    BOOL val_b;
};

struct mb_node
{
    int key;
    int type;
    int addr;
    union val;
};

struct mb_node_list
{
    struct mb_node node;
    struct list_head list;
};

//线程操作函数1
void *thread(void *arg)
{
    struct mb_node mb_command;
    //先从消息队列中获取控制命令
    msg_client_init(&msg_para, MODULE,"msgs_control_gather");
    while(1)
    {
        msg_client_recv(&msg_para, &mb_command, sizeof(mb_node_list));
        //TODO
    }
}


int conver_endian_long(unsigned char *dst, const unsigned char *src, int len)
{
    int i = 0;

    if(len % 4 != 0){
        printf("err len\n");
        return -1;
    }

    while (i < len) {
        dst[i] = src[i+3];
        dst[i+1] = src[i+2];
        dst[i+2] = src[i+1];
        dst[i+3] = src[i];
        i += 4;
    }

    return 0;
}

int main(int argc, char *argv[])
{
    // 0定义变量
    int sockfd;
    pthread_t tid;
    int a = 20;
    char buf[N];
    int addrlen = sizeof(struct sockaddr);
    struct sockaddr_in serveraddr;

    if(argc != 3){
        printf("usage: %s <ip> <port>\n", argv[0]);
        return -1;
    }

    // 1创建一个套接字--socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0){
        perror("socket err");
        exit(-1);
    }

    // 2指定服务器地址--sockaddr_in
    bzero(&serveraddr, addrlen);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));

    // 3连接服务器--connect
    if(connect(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){
        perror("connect err");
        exit(-1);
    }
    printf("服务器连接成功!\n");
    
    /*
    02 b7：事务标识符，类似与TCP里的seq和ack，可以随意写，回复和发送的会一致
    00 00：协议标识符，00 00表示ModbusTCP协议
    00 06：表示接下来的数据长度，单位为字节
    01：单元标识符，即新建寄存器表时候的从机ID，默认是1。
    03：功能码，我们现在读的是保持寄存器，所以是03
    00 00：读取的起始寄存器地址
    00 01：读取的寄存器个数 */

    

    //接收缓冲区
    unsigned char recv_buf[128] = {0};
    
    if(pthread_create(&tid,NULL,thread,&a) != 0)
	{
		perror("pthread_create err.");
		return -1;
	}
    while(1)
    {
        send(sockfd, send_buf, 12, 0);
        int ret = recv(sockfd, recv_buf, 128, 0);
        if(ret < 0)
        {
            perror("recv err");
            continue;
        }

        int i;
        for(i=0; i<ret; i++)
        {
            //将接收的内容打印出来看看
            printf("%02x ", recv_buf[i]);
        }
        printf("\n");

        //解析出需要的数据来
        float *p = recv_buf + 9;  //将指针偏移到数据位置

/*
#if 1   //因为接收的数据是按照大端ABCD存储的，而我们的CPU是小端模式，所以要将字节序置换     
        float data;
        conver_endian_long(&data, p, 4);
#else   //如果接收数据格式是DCBCA（小端）存储，那么就简单了，直接定义一个float类型指针变量，指向这四个字节即可取出值来
        float data = *p;
#endif*/

		float data = *p;
        printf("temp = %0.2f\n", data);

        //将数据结构体发送到共享内存中
        sleep(1);
    }


    // 5关闭连接--close
    close(sockfd);
}
